package com.itita.ww2.game.cityconstruction;

import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itita.ww2.core.TaskPerSecond;
import com.itita.ww2.core.TaskPerSecond.ITimerCondition;
import com.itita.ww2.core.WW2Exception;
import com.itita.ww2.data.CityConstructionCfg;
import com.itita.ww2.data.CityConstructionCfg.RefreshTime;
import com.itita.ww2.data.CityConstructionCfg.SchemeType;
import com.itita.ww2.enums.WW2ExceptionCode;
import com.itita.ww2.game.alliance.AllianceManager;
import com.itita.ww2.game.user.UserRewardDispatch.RewardType;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.model.worldmap.City;
import com.itita.ww2.model.worldmap.enums.CityType;
import com.itita.ww2.puredb.model.Alliance;
import com.itita.ww2.puredb.model.UserCityConstruction;
import com.itita.ww2.puredb.model.UserCityConstructionTime;
import com.itita.ww2.puredb.model.UserCitySpecialCollect;
import com.itita.ww2.utils.TimeUtil;
import com.itita.ww2.utils.UUIDGenerator;
import com.smartfoxserver.v2.entities.data.ISFSArray;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.entities.data.SFSObject;

/**
 * 城池建设
 * @author NorthLan
 *
 */
public class CityConstructionService {
	private CityConstructionService() {
	}

	@SuppressWarnings("unused")
	private static final Logger logger = LoggerFactory.getLogger(CityConstructionService.class);

	/**
	 * 获取玩家今日已领取特产的对应城池列表
	 */
	public static final ISFSArray getAllUserCollectedSpcial(UserProfile userProfile) {
		ISFSArray ref = SFSArray.newInstance();
		UserCitySpecialCollect m_Ucsc = UserCitySpecialCollect.getByUid(userProfile.getUid());
		if (m_Ucsc == null) {
			return ref;
		}
		for (City city : m_Ucsc.getCollectedList()) {
			ISFSObject obj = SFSObject.newInstance();
			obj.putInt("blockId", city.getBlockId());
			obj.putInt("cityId", city.getId());
			ref.addSFSObject(obj);
		}
		return ref;
	}

	/**
	 * 领取特产
	 */
	public static final ISFSObject takeSpecialProduct(UserProfile userProfile, int blockId, int cityId)
			throws WW2Exception {
		if (!userProfile.isJoinAlliance()) {
			throw new WW2Exception(WW2ExceptionCode.ALLIANCE_HAS_NOT_JOIN);
		}
		// 检查是否已领取过
		UserCitySpecialCollect m_Ucsc = UserCitySpecialCollect.getByUid(userProfile.getUid());
		if (m_Ucsc != null) {
			if (m_Ucsc.contains(blockId, cityId)) {
				throw new WW2Exception(WW2ExceptionCode.DUPLICATE_OPT);
			}
		}
		ISFSObject fixed_output = CityConstructionCfg.getCityFixedSpecialProduct(blockId, cityId);
		ISFSObject week_output = CityConstructionCfg.getCityWeekSpecialProduct(blockId, cityId,
				TimeUtil.getNowDayOfWeekShortText());
		ISFSObject params = SFSObject.newInstance();
		params.putSFSObject("fixed_output", fixed_output);
		params.putSFSObject("week_output", week_output);
		userProfile.getRewardManager().onReward(RewardType.CITY_SPECIAL_PRODUCT, params);

		if (m_Ucsc == null) {
			m_Ucsc = new UserCitySpecialCollect();
			m_Ucsc.setUid(userProfile.getUid());
			m_Ucsc.addCollected(blockId, cityId);
			m_Ucsc.setLastTime(TimeUtil.getUtcNowMillis());
			m_Ucsc.insert();
		} else {
			m_Ucsc.addCollected(blockId, cityId);
			m_Ucsc.setLastTime(TimeUtil.getUtcNowMillis());
			m_Ucsc.update();
		}

		// back data
		ISFSObject ref = SFSObject.newInstance();
		for (String key : fixed_output.getKeys()) {
			if (ref.containsKey(key)) {
				ref.putInt(key, ref.getInt(key) + fixed_output.getInt(key));
			} else {
				ref.putInt(key, fixed_output.getInt(key));
			}
		}
		for (String key : week_output.getKeys()) {
			if (ref.containsKey(key)) {
				ref.putInt(key, ref.getInt(key) + week_output.getInt(key));
			} else {
				ref.putInt(key, week_output.getInt(key));
			}
		}
		return ref;
	}

	public static final ISFSArray getAllUserConstruction(UserProfile userProfile) {
		ISFSArray ref = SFSArray.newInstance();
		List<UserCityConstruction> m_UccList = UserCityConstruction.getByUid(userProfile.getUid());
		int size = m_UccList.size();
		for (int i = 0; i < size; ++i) {
			ref.addSFSObject(m_UccList.get(i).toSFSObject());
		}
		return ref;
	}

	public static final boolean userHasAnyConstruction(UserProfile userProfile) {
		return UserCityConstruction.anyConstructionExists(userProfile.getUid());
	}

	/**
	 * 收集建设资源
	 * @return 下一次收集时间间隔 (s)
	 */
	public static final ISFSObject collectConstructionRes(UserProfile userProfile) throws WW2Exception {
		ISFSObject backObj = SFSObject.newInstance();

		UserCityConstructionTime m_Ucct = UserCityConstructionTime.getByUid(userProfile.getUid());
		if (m_Ucct == null) {
			throw new WW2Exception(WW2ExceptionCode.SQLEXCEPTION); // 找不到时间
		}
		Alliance alliance = null;
		if (userProfile.isJoinAlliance()) {
			alliance = AllianceManager.getInstance().getAlliance(userProfile.getAid());
		}

		long nowTime = TimeUtil.getUtcNowMillis();
		int interval = CityConstructionCfg.getOutInterval();
		int sec = (int) ((nowTime - m_Ucct.getRefreshTime()) / 1000);
		if (sec < interval) {
			backObj.putInt("refreshTime", interval -= sec);
			return backObj;
		}
		// 获取该玩家所有建设
		List<UserCityConstruction> m_UccList = UserCityConstruction.getByUid(userProfile.getUid());

		List<UserCityConstruction> m_UccListModify = new ArrayList<>();
		int size = m_UccList.size();
		for (int i = 0; i < size; ++i) {
			UserCityConstruction item = m_UccList.get(i);
			int val = sec / 3600 * CityConstructionCfg.getOutputReal(item.getCode(), item.getLv(), item.getScheme());
			// 添加对应资源
			userProfile.getResManager().operResWithCheck(CityConstructionCfg.getOutputType(item.getCode()), val);
			int tempScheme = item.getScheme();
			setConstructionScheme(item, alliance);
			if (item.getScheme() != tempScheme) {
				m_UccListModify.add(item);
			}
		}
		UserCityConstruction.updateSchemeBatch(m_UccListModify);

		// 更新时间
		m_Ucct.setRefreshTime(TimeUtil.getUtcNowMillis());
		m_Ucct.update();

		userProfile.getResManager().sync();

		// 新的数据
		ISFSArray mList = SFSArray.newInstance();
		int mSize = m_UccListModify.size();
		for (int i = 0; i < mSize; ++i) {
			UserCityConstruction item = m_UccListModify.get(i);
			ISFSObject obj = SFSObject.newInstance();
			obj.putUtfString("uuid", item.getUuid());
			obj.putInt("scheme", item.getScheme());
			mList.addSFSObject(obj);
		}
		backObj.putSFSArray("mList", mList);
		backObj.putInt("refreshTime", interval);
		return backObj;
	}

	/**
	 * 升级产业
	 */
	public static final void upgradeConstruction(UserProfile userProfile, String uuid) throws WW2Exception {
		UserCityConstruction m_Ucc = UserCityConstruction.getByUUID(uuid);
		if (m_Ucc == null) {
			throw new WW2Exception(WW2ExceptionCode.INVALID_OPT);
		}

		// 等级不能大于指挥官等级
		if (m_Ucc.getLv() >= userProfile.getUserInfo().getLevel()) {
			throw new WW2Exception(WW2ExceptionCode.LEVEL_LIMIT);
		}

		ISFSObject resObj = CityConstructionCfg.getUpgradeResource(m_Ucc.getCode(), m_Ucc.getLv());
		if (!userProfile.getResManager().isResEnoughMulti(resObj)) {
			throw new WW2Exception(WW2ExceptionCode.USER_RES_NOT_ENOUGH);
		}
		userProfile.getResManager().operResWithMaxCheck(resObj, false);
		userProfile.getResManager().update();
		userProfile.getResManager().sync();

		// 升级
		m_Ucc.setLv(m_Ucc.getLv() + 1);
		m_Ucc.update();
	}

	/**
	 * 舍弃产业
	 */
	public static final void discardConstruction(UserProfile userProfile, String uuid) throws WW2Exception {
		UserCityConstruction m_Ucc = UserCityConstruction.getByUUID(uuid);
		if (m_Ucc == null) {
			throw new WW2Exception(WW2ExceptionCode.DUPLICATE_OPT);
		}
		m_Ucc.delete();
		// 如果产业完全舍弃,则删除时间
		if (!UserCityConstruction.anyConstructionExists(userProfile.getUid())) {
			UserCityConstructionTime.delete(userProfile.getUid());
		}
	}

	/**
	 * 购买产业
	 */
	public static final ISFSObject buyConstruction(UserProfile userProfile, City city, String code)
			throws WW2Exception {
		// 每个城的每种产业,玩家只可购买一次
		if (UserCityConstruction.cityConstructionExists(userProfile.getUid(), code, city.getBlockId(), city.getId())) {
			throw new WW2Exception(WW2ExceptionCode.DUPLICATE_OPT);
		}
		int userLimit = CityConstructionCfg.getSingleBuyLimit(0);
		Alliance alliance = AllianceManager.getInstance().getAlliance(userProfile.getAid());
		if (alliance != null) {
			userLimit = CityConstructionCfg.getSingleBuyLimit(alliance.getLevel());
		}
		if (UserCityConstruction.getUserConstructionCount(code, userProfile.getUid()) >= userLimit) {
			throw new WW2Exception(WW2ExceptionCode.BUY_LIMIT);
		}

		// 判断资源条件
		ISFSObject buyRes = CityConstructionCfg.getBuyResource(code);
		if (!userProfile.getResManager().isResEnoughMulti(buyRes)) {
			throw new WW2Exception(WW2ExceptionCode.USER_RES_NOT_ENOUGH);
		}
		// 购买
		userProfile.getResManager().operResWithMaxCheck(buyRes, false);
		userProfile.getResManager().update();
		userProfile.getResManager().sync();

		UserCityConstruction ucc = new UserCityConstruction();
		ucc.setUid(userProfile.getUid());
		ucc.setCode(code);
		//		ucc.setBlockId(city.getBlockId());
		//		ucc.setCityId(city.getId());
		ucc.setCity(city);
		ucc.setBuyTime(TimeUtil.getUtcNowMillis());
		ucc.setLv(1);
		ucc.setUuid(UUIDGenerator.nextConstructionId());
		setConstructionScheme(ucc, alliance);
		ucc.insert();

		ISFSObject backObj = SFSObject.newInstance();
		backObj.putSFSObject("obj", ucc.toSFSObject());

		// 若玩家首次购买产业,设置刷新时间
		boolean hasRefreshTime = !UserCityConstructionTime.hasRefreshTime(userProfile.getUid());
		if (hasRefreshTime) {
			UserCityConstructionTime m_Ucct = new UserCityConstructionTime();
			m_Ucct.setUid(userProfile.getUid());
			m_Ucct.setRefreshTime(TimeUtil.getUtcNowMillis());
			m_Ucct.insert();

			backObj.putInt("refreshTime", CityConstructionCfg.getOutInterval());
		}
		return backObj;
	}

	/**
	 * 设置资源获取方案
	 */
	private static final void setConstructionScheme(UserCityConstruction construction, Alliance alliance) {
		City city = construction.getCity();
		CityType cityType = city.getType();
		construction.setScheme(SchemeType.NORMAL.ordinal());
		if (alliance != null && cityType == CityType.CAPTICAL) {
			if (alliance.getAid().equalsIgnoreCase(city.getOwnerAid())) {
				construction.setScheme(SchemeType.CAPTICAL.ordinal());
			}
		}
	}

	/**
	 * 启动定时任务,每天X点刷新一波 领取特产
	 */
	public static final void startRefreshCitySpecialProductTask() {
		// 获取刷新时间点
		TaskPerSecond.addTask(CityConstructionCfg.specialProductRefreshTask, new ITimerCondition() {
			@Override
			public boolean condition() {
				RefreshTime rt = CityConstructionCfg.getRefreshTime();
				DateTime upTime = TimeUtil.getDateTimeWithZoneTimeOfDay(rt.getZoneId(), rt.getHour(), rt.getMinute(), 0,
						0);
				return TimeUtil.getUtcNow().isEqual(upTime);
			}
		}, () -> {
			UserCitySpecialCollect.deleteAll();
		}, false);
	}
}
